package com.example.test_app.Util;

import android.app.KeyguardManager;
import android.content.Context;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Build;
import android.os.CancellationSignal;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
import android.widget.Toast;

import com.example.test_app.MainActivity;

import java.security.KeyStore;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

public class FingerprintUtil {
    private static final String DEFAULT_KEY_NAME = "aa";
    private Context context;
    private FingerprintManager fingerprintManager;
    public FingerprintUtil(Context context) {
        this.context = context;
        if (supportFingerprint ()) {
            initKey();
            initCipher();
        }
    }

    public boolean supportFingerprint () {
        if (Build.VERSION.SDK_INT < 23) {
            return false;
        } else {
            KeyguardManager keyguardManager = context.getSystemService(KeyguardManager.class);
            fingerprintManager = context.getSystemService(FingerprintManager.class);
            if (!fingerprintManager.isHardwareDetected()) {
                return false;
            } else if (!keyguardManager.isKeyguardSecure()) {
                return false;
            } else if (!fingerprintManager.hasEnrolledFingerprints()) {
                return false;
            }
        }
        return true;

    }

    KeyStore keyStore;
    private void initKey() {
        try {
            keyStore = KeyStore.getInstance("AndroidKeyStore");
            keyStore.load(null);
            KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
            KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(DEFAULT_KEY_NAME,
                    KeyProperties.PURPOSE_ENCRYPT |
                            KeyProperties.PURPOSE_DECRYPT)
                    .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
                    .setUserAuthenticationRequired(true)
                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7);
            keyGenerator.init(builder.build());
            keyGenerator.generateKey();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    Cipher cipher;
    private void initCipher() {
        try {
            SecretKey key = (SecretKey) keyStore.getKey(DEFAULT_KEY_NAME, null);
            cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
                    + KeyProperties.BLOCK_MODE_CBC + "/"
                    + KeyProperties.ENCRYPTION_PADDING_PKCS7);
            cipher.init(Cipher.ENCRYPT_MODE, key);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    CancellationSignal mCancellationSignal;
    boolean isSelfCancelled;
    public void startListening(FingerprintManager.AuthenticationCallback callback) {
       if (supportFingerprint ()) {
           isSelfCancelled = false;
           mCancellationSignal = new CancellationSignal();
           /**
            * authenticate()方法接收五个参数，
            * 第一个参数是CryptoObject对象，传入Cipher对象就可以了。
            * 第二个参数是CancellationSignal对象，可以使用它来取消指纹认证操作。
            * 第三个参数是可选参数，官方的建议是直接传0就可以了。
            * 第四个参数用于接收指纹认证的回调，上述代码中将所有的回调可能都进行了界面提示。
            * 第五个参数用于指定处理回调的Handler，这里直接传null表示回调到主线程即可
            */

           fingerprintManager.authenticate(new FingerprintManager.CryptoObject(cipher), mCancellationSignal, 0, callback
                   , null);
       }
    }

    /**
     * 调用CancellationSignal的cancel()方法将指纹认证操作
     */
    public void stopListening() {
        if (mCancellationSignal != null) {
            mCancellationSignal.cancel();
            mCancellationSignal = null;
            isSelfCancelled = true;
        }

    }
}
